package com.mockapi.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mockapi.dto.HttpEventConfig;
import com.mockapi.entity.Event;
import com.mockapi.entity.EventTrigger;
import com.mockapi.util.FreeMarkerUtil;
import com.mockapi.util.JsonUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * HTTP事件执行器
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class HttpEventExecutor implements EventExecutor {

    private final RestTemplate restTemplate;

    @Override
    public EventTrigger execute(Event event, Map<String, Object> context) {
        long startTime = System.currentTimeMillis();
        EventTrigger trigger = createTrigger(event, context);
        
        try {
            // 解析HTTP配置
            HttpEventConfig config = JsonUtils.parseObject(event.getEventConfig(), HttpEventConfig.class);
            if (config == null) {
                throw new RuntimeException("HTTP事件配置错误");
            }

            // 使用FreeMarker渲染URL
            String renderedUrl = FreeMarkerUtil.renderTemplate(config.getUrl(), context);
            
            // 使用FreeMarker渲染请求头
            HttpHeaders httpHeaders = new HttpHeaders();
            if (config.getHeaders() != null) {
                for (Map.Entry<String, String> entry : config.getHeaders().entrySet()) {
                    String key = entry.getKey();
                    String value = FreeMarkerUtil.renderTemplate(entry.getValue(), context);
                    httpHeaders.set(key, value);
                }
            }
            
            // 使用FreeMarker渲染请求体
            Object requestBody = null;
            if (config.getBody() != null) {
                requestBody = FreeMarkerUtil.renderTemplate(config.getBody(), context);
            }
            
            // 创建HTTP实体
            HttpEntity<Object> httpEntity = new HttpEntity<>(requestBody, httpHeaders);
            
            // 执行请求
            ResponseEntity<String> responseEntity = restTemplate.exchange(
                renderedUrl, 
                HttpMethod.valueOf(config.getMethod().toUpperCase()), 
                httpEntity, 
                String.class
            );
            
            String response = responseEntity.getBody();
            
            // 更新触发记录
            long executionTime = System.currentTimeMillis() - startTime;
            trigger.setExecutionStatus("SUCCESS");
            trigger.setResponseData(response);
            trigger.setExecutionTimeMs((int) executionTime);
            
            log.info("HTTP事件执行成功: eventId={}, url={}, executionTime={}ms", 
                    event.getId(), renderedUrl, executionTime);
            
        } catch (Exception e) {
            long executionTime = System.currentTimeMillis() - startTime;
            trigger.setExecutionStatus("FAILED");
            trigger.setErrorMessage(e.getMessage());
            trigger.setExecutionTimeMs((int) executionTime);
            
            log.error("HTTP事件执行失败: eventId={}, error={}", event.getId(), e.getMessage(), e);
        }
        
        return trigger;
    }

    @Override
    public EventTrigger retry(Event event, EventTrigger trigger, Map<String, Object> context) {
        trigger.setRetryCount(trigger.getRetryCount() + 1);
        trigger.setExecutionStatus("RUNNING");
        trigger.setUpdatedAt(LocalDateTime.now());
        
        // 延迟重试
        try {
            Thread.sleep(event.getRetryInterval());
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        return execute(event, context);
    }

    @Override
    public String getSupportedEventType() {
        return "HTTP";
    }

    private EventTrigger createTrigger(Event event, Map<String, Object> context) {
        EventTrigger trigger = new EventTrigger();
        trigger.setEventId(event.getId());
        trigger.setTriggerTime(LocalDateTime.now());
        trigger.setTriggerType(context.get("triggerType").toString());
        trigger.setTriggerSource(context.get("triggerSource").toString());
        trigger.setExecutionStatus("RUNNING");
        trigger.setRequestData(JsonUtils.toJsonString(context));
        trigger.setRetryCount(0);
        return trigger;
    }
} 